package com.zx.template.task;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import com.zx.template.entity.UserResumeDO;
import com.zx.template.mapper.UserResumeMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.Date;
import java.util.concurrent.DelayQueue;


@Slf4j
@RestController
@RequestMapping("/delay")
public class TestDelayQueueController {
    private static final DelayQueue<DelayedMessage> delayQueue = new DelayQueue<>();
    
    @Resource
    UserResumeMapper userResumeMapper;

    /**
     * 这种直接导致 线程一直轮询，会导致cpu占用很高，不应该使用
     */
    public void initDelayQueue(){
        delayQueue.put(DelayedMessage.builder().msg("消息2030年").delaySeconds(232003962 + System.currentTimeMillis() / 1000).build());
       new Thread(() -> {
           while (!delayQueue.isEmpty()) {
               // 取队列头部元素是否过期
               DelayedMessage task = delayQueue.poll();
               if (task != null) {
                   // 去消费
                   handleBusiness(task);
               }
           }
       }).start();
    }

    public TestDelayQueueController() {
        initDelayQueue();
    }

    @GetMapping("/handleEvent")
    public String handleEvent(){
        int rand = RandomUtil.randomInt(30);
        // 期望被消费时间
        DateTime runExpectTime = DateUtil.offsetSecond(new Date(), rand);

        long l = DateUtil.between(runExpectTime, new Date(), DateUnit.SECOND);
        log.error("延时{}秒",l);
        delayQueue.put(DelayedMessage.builder().msg("消息" + rand).delaySeconds(l + System.currentTimeMillis() / 1000).build());
        return "执行成功";
    }

    public  void handleBusiness(DelayedMessage dto) {
        log.info("消费了一条消息：{}", dto);
        userResumeMapper.insert(UserResumeDO.builder().userId(111L).roleName("1111").build());
    }
}
